//最简单的加载了一个GDALImageLayer图层的完整shader列表。
////////////////////////////////////////shaderlist[0]
#version 460
#pragma vp_function oe_pbr_init, fragment, first
#define VP_STAGE_FRAGMENT
// fragment stage global PBR parameters.
struct OE_PBR {
    float roughness;
    float ao;
    float metal;
    float brightness;
    float contrast;
} oe_pbr;
void oe_pbr_init(inout vec4 ignore_me)
{
    oe_pbr.roughness = 1.0;
    oe_pbr.ao = 1.0;
    oe_pbr.metal = 0.0;
    oe_pbr.brightness = 1.0;
    oe_pbr.contrast = 1.0;
}
////////////////////////////////////////shaderlist[1]
#version 460
#pragma import_defines(OE_CLIPPLANE_NUM)
// OSG built-in to transform from view to world
uniform mat4 osg_ViewMatrixInverse;
// clipping plane
uniform vec4 oe_ClipPlane_plane;
void oe_ClipPlane_vs(inout vec4 vertex_view)
        {
        #ifndef GL_ES
            gl_ClipDistance[OE_CLIPPLANE_NUM] = dot(osg_ViewMatrixInverse * vertex_view, oe_ClipPlane_plane);
        #endif
        }
////////////////////////////////////////shaderlist[2]
#version 460
#pragma vp_name Rex Terrain SDK
#define VP_STAGE_VERTEX
uniform sampler2D oe_tile_elevationTex;
uniform mat4 oe_tile_elevationTexMatrix;
uniform sampler2D oe_tile_normalTex;
uniform mat4 oe_tile_normalTexMatrix;
// SDK functions for the Rex engine.
// Declare and call these from any shader that runs on the terrain.
// uniforms from terrain engine
uniform vec2 oe_tile_elevTexelCoeff;
// Stage global
vec4 oe_layer_tilec;
vec4 oe_tile_key;
// Sample the elevation data at a UV tile coordinate.
float oe_terrain_getElevation(in vec2 uv)
{
    // Texel-level scale and bias allow us to sample the elevation texture
    // on texel center instead of edge.
    vec2 uv_scaledBiased = uv
        * oe_tile_elevTexelCoeff.x * oe_tile_elevationTexMatrix[0][0]     // scale
        + oe_tile_elevTexelCoeff.x * oe_tile_elevationTexMatrix[3].st     // bias
        + oe_tile_elevTexelCoeff.y;
    return texture(oe_tile_elevationTex, uv_scaledBiased).r;
}
// Read the elevation at the build-in tile coordinates (convenience)
float oe_terrain_getElevation()
{
    return oe_terrain_getElevation(oe_layer_tilec.st);
}
// Read the normal vector and curvature at resolved UV tile coordinates.
vec4 oe_terrain_getNormalAndCurvature(in vec2 uv_scaledBiased)
{
    vec4 n = texture(oe_tile_normalTex, uv_scaledBiased);
    n.xyz = n.xyz*2.0-1.0;
    float curv = n.z;
    n.z = 1.0 - abs(n.x) - abs(n.y);
    // unnecessary since Z is never < 0:
    //float t = clamp(-n.z, 0, 1);
    //n.x += (n.x > 0)? -t : t;
    //n.y += (n.y > 0)? -t : t;
    return vec4(normalize(n.xyz), curv);
}
vec4 oe_terrain_getNormalAndCurvature()
{
    vec2 uv_scaledBiased = oe_layer_tilec.st
        * oe_tile_elevTexelCoeff.x * oe_tile_normalTexMatrix[0][0]
        + oe_tile_elevTexelCoeff.x * oe_tile_normalTexMatrix[3].st
        + oe_tile_elevTexelCoeff.y;
    return oe_terrain_getNormalAndCurvature(uv_scaledBiased);
}
#ifndef VP_FRAGMENT_STAGE
/**
 * Scales repeating texture coordinate such that they are [0..1]
 * at a specific reference tile LOD. 
 */
vec2 oe_terrain_scaleCoordsToRefLOD(in vec2 tc, in float refLOD)
{
    float dL = oe_tile_key.z - refLOD;
    float factor = exp2(dL);
    float invFactor = 1.0/factor;
    vec2 result = tc * vec2(invFactor);
    vec2 a = floor(oe_tile_key.xy * invFactor);
    vec2 b = a * factor;
    vec2 c = b + factor;
    float m = floor(clamp(factor,0.0,1.0)); // if factor>=1.0
    result += m*(oe_tile_key.xy-b)/(c-b);
    return result;
}
/**
 * Scales repeating texture coordinate such that they are [0..1]
 * at a specific reference tile LOD.
 */
vec4 oe_terrain_scaleCoordsAndTileKeyToRefLOD(in vec2 tc, in float refLOD)
{
    float dL = oe_tile_key.z - refLOD;
    float factor = exp2(dL);
    float invFactor = 1.0 / factor;
    vec2 result = tc * vec2(invFactor);
    vec2 a = floor(oe_tile_key.xy * invFactor);
    vec2 b = a * factor;
    vec2 c = b + factor;
    float m = floor(clamp(factor, 0.0, 1.0)); // if factor>=1.0
    result += m * (oe_tile_key.xy - b) / (c - b);
    return vec4(result, a);
}
#endif
////////////////////////////////////////shaderlist[3]
#version 460
#pragma vp_name Rex Terrain SDK
#define VP_STAGE_FRAGMENT
uniform sampler2D oe_tile_elevationTex;
uniform mat4 oe_tile_elevationTexMatrix;
uniform sampler2D oe_tile_normalTex;
uniform mat4 oe_tile_normalTexMatrix;
// SDK functions for the Rex engine.
// Declare and call these from any shader that runs on the terrain.
// uniforms from terrain engine
uniform vec2 oe_tile_elevTexelCoeff;
// Stage global
vec4 oe_layer_tilec;
vec4 oe_tile_key;
// Sample the elevation data at a UV tile coordinate.
float oe_terrain_getElevation(in vec2 uv)
{
    // Texel-level scale and bias allow us to sample the elevation texture
    // on texel center instead of edge.
    vec2 uv_scaledBiased = uv
        * oe_tile_elevTexelCoeff.x * oe_tile_elevationTexMatrix[0][0]     // scale
        + oe_tile_elevTexelCoeff.x * oe_tile_elevationTexMatrix[3].st     // bias
        + oe_tile_elevTexelCoeff.y;
    return texture(oe_tile_elevationTex, uv_scaledBiased).r;
}
// Read the elevation at the build-in tile coordinates (convenience)
float oe_terrain_getElevation()
{
    return oe_terrain_getElevation(oe_layer_tilec.st);
}
// Read the normal vector and curvature at resolved UV tile coordinates.
vec4 oe_terrain_getNormalAndCurvature(in vec2 uv_scaledBiased)
{
    vec4 n = texture(oe_tile_normalTex, uv_scaledBiased);
    n.xyz = n.xyz*2.0-1.0;
    float curv = n.z;
    n.z = 1.0 - abs(n.x) - abs(n.y);
    // unnecessary since Z is never < 0:
    //float t = clamp(-n.z, 0, 1);
    //n.x += (n.x > 0)? -t : t;
    //n.y += (n.y > 0)? -t : t;
    return vec4(normalize(n.xyz), curv);
}
vec4 oe_terrain_getNormalAndCurvature()
{
    vec2 uv_scaledBiased = oe_layer_tilec.st
        * oe_tile_elevTexelCoeff.x * oe_tile_normalTexMatrix[0][0]
        + oe_tile_elevTexelCoeff.x * oe_tile_normalTexMatrix[3].st
        + oe_tile_elevTexelCoeff.y;
    return oe_terrain_getNormalAndCurvature(uv_scaledBiased);
}
#ifndef VP_FRAGMENT_STAGE
/**
 * Scales repeating texture coordinate such that they are [0..1]
 * at a specific reference tile LOD. 
 */
vec2 oe_terrain_scaleCoordsToRefLOD(in vec2 tc, in float refLOD)
{
    float dL = oe_tile_key.z - refLOD;
    float factor = exp2(dL);
    float invFactor = 1.0/factor;
    vec2 result = tc * vec2(invFactor);
    vec2 a = floor(oe_tile_key.xy * invFactor);
    vec2 b = a * factor;
    vec2 c = b + factor;
    float m = floor(clamp(factor,0.0,1.0)); // if factor>=1.0
    result += m*(oe_tile_key.xy-b)/(c-b);
    return result;
}
/**
 * Scales repeating texture coordinate such that they are [0..1]
 * at a specific reference tile LOD.
 */
vec4 oe_terrain_scaleCoordsAndTileKeyToRefLOD(in vec2 tc, in float refLOD)
{
    float dL = oe_tile_key.z - refLOD;
    float factor = exp2(dL);
    float invFactor = 1.0 / factor;
    vec2 result = tc * vec2(invFactor);
    vec2 a = floor(oe_tile_key.xy * invFactor);
    vec2 b = a * factor;
    vec2 c = b + factor;
    float m = floor(clamp(factor, 0.0, 1.0)); // if factor>=1.0
    result += m * (oe_tile_key.xy - b) / (c - b);
    return vec4(result, a);
}
#endif
////////////////////////////////////////shaderlist[4]
#version 460
#pragma vp_name REX Engine - Init Model Space
#pragma vp_function oe_rex_init_model, vertex_model, first
#define VP_STAGE_VERTEX
// uniforms
uniform vec4 oe_terrain_color;
uniform vec4 oe_tile_key_u;
// outputs
vec4 vp_Color;
#pragma vp_varying_out vec4 vp_Color
vec4 oe_layer_tilec;
#pragma vp_varying_out vec4 oe_layer_tilec
vec4 oe_terrain_tessLevel;
#pragma vp_varying_out vec4 oe_terrain_tessLevel
float oe_rex_morphFactor;
#pragma vp_varying_out float oe_rex_morphFactor
int oe_terrain_vertexMarker;
#pragma vp_varying_out flat int oe_terrain_vertexMarker
// stage globals
vec4 oe_tile_key;
void oe_rex_init_model(inout vec4 vertexModel)
{
    // Texture coordinate for the tile (always 0..1)
    oe_layer_tilec = gl_MultiTexCoord0;
    // Extract the vertex type marker
    oe_terrain_vertexMarker = int(oe_layer_tilec.z);
    // Color of the underlying map geometry (untextured)
    vp_Color = oe_terrain_color;
    // initialize:
    oe_rex_morphFactor = 0.0;
    // tile key
    oe_tile_key = oe_tile_key_u;
    
    // Default tessellation level (where applicable)
    oe_terrain_tessLevel = vec4(1);
}
////////////////////////////////////////shaderlist[5]
#version 460
#pragma vp_name REX Engine - Init View Space
#pragma vp_function oe_rex_init_view, vertex_view, first
#define VP_STAGE_VERTEX
// outputs
vec3 vp_Normal;
#pragma vp_varying_out vec3 vp_Normal
vec3 oe_UpVectorView;
#pragma vp_varying_out vec3 oe_UpVectorView
void oe_rex_init_view(inout vec4 vert_view)
{
    //  up  vector at this vertex in view space, which we will later
    // need in order to elevate the terrain. vp_Normal can change later
    // but UpVectorView will stay the same.
    oe_UpVectorView = vp_Normal;
}
////////////////////////////////////////shaderlist[6]
#version 460
#pragma vp_name REX Engine - Elevation
#pragma vp_function oe_rex_applyElevation, vertex_view, 0.1
#pragma import_defines(OE_TERRAIN_RENDER_ELEVATION)
#define VP_STAGE_VERTEX
// Vertex Markers:
#define VERTEX_VISIBLE  1
#define VERTEX_BOUNDARY 2
#define VERTEX_HAS_ELEVATION 4
#define VERTEX_SKIRT 8
#define VERTEX_CONSTRAINT 16
// stage
vec4 oe_layer_tilec;
#pragma vp_varying_out vec4 oe_layer_tilec
vec3 oe_UpVectorView;
#pragma vp_varying_out vec3 oe_UpVectorView
int oe_terrain_vertexMarker;
#pragma vp_varying_out flat int oe_terrain_vertexMarker
uniform float oe_terrain_altitude;
// SDK functions:
float oe_terrain_getElevation();
void oe_rex_applyElevation(inout vec4 vertex)
{
#ifdef OE_TERRAIN_RENDER_ELEVATION
    bool elevate =
        ((oe_terrain_vertexMarker & VERTEX_VISIBLE) != 0) &&
        ((oe_terrain_vertexMarker & VERTEX_HAS_ELEVATION) == 0);
    float elev = elevate ? oe_terrain_getElevation() : 0.0;
    vertex.xyz += oe_UpVectorView * elev;
#endif
    vertex.xyz += oe_UpVectorView * oe_terrain_altitude;
}

////////////////////////////////////////shaderlist[7]
#version 460
#pragma vp_entryPoint oe_rex_normalMapVS
#pragma vp_location   vertex_view
#pragma vp_order      0.5
#pragma import_defines(OE_TERRAIN_RENDER_NORMAL_MAP)
#define VP_STAGE_VERTEX
uniform mat4 oe_tile_normalTexMatrix;
uniform vec2 oe_tile_elevTexelCoeff;
uniform mat4 oe_tile_elevationTexMatrix;
// stage globals
vec4 oe_layer_tilec;
#pragma vp_varying_out vec4 oe_layer_tilec
vec2 oe_normal_uv;
#pragma vp_varying_out vec2 oe_normal_uv
vec3 oe_normal_binormal;
#pragma vp_varying_out vec3 oe_normal_binormal
void oe_rex_normalMapVS(inout vec4 unused)
{
#ifndef OE_TERRAIN_RENDER_NORMAL_MAP
    return;
#endif
    // calculate the sampling coordinates for the normal texture
    //oe_normalMapCoords = (oe_tile_normalTexMatrix * oe_layer_tilec).st;
    //oe_normalMapCoords = oe_layer_tilec.st
    //    * oe_tile_elevTexelCoeff.x * oe_tile_normalTexMatrix[0][0]
    //    + oe_tile_elevTexelCoeff.x * oe_tile_normalTexMatrix[3].st
    //    + oe_tile_elevTexelCoeff.y;
    oe_normal_uv = oe_layer_tilec.st
        * oe_tile_elevTexelCoeff.x * oe_tile_elevationTexMatrix[0][0]
        + oe_tile_elevTexelCoeff.x * oe_tile_elevationTexMatrix[3].st
        + oe_tile_elevTexelCoeff.y;
    // send the bi-normal to the fragment shader
    oe_normal_binormal = normalize(gl_NormalMatrix * vec3(0, 1, 0));
}

////////////////////////////////////////shaderlist[8]
#version 460
#pragma vp_entryPoint oe_rex_normalMapFS
#pragma vp_location   fragment_coloring
#pragma vp_order      0.1
#pragma import_defines(OE_TERRAIN_RENDER_NORMAL_MAP)
#pragma import_defines(OE_DEBUG_NORMALS)
#pragma import_defines(OE_DEBUG_CURVATURE)
#define VP_STAGE_FRAGMENT
// import terrain SDK
vec4 oe_terrain_getNormalAndCurvature(in vec2);
uniform sampler2D oe_tile_normalTex;
vec3 vp_Normal;
#pragma vp_varying_in vec3 vp_Normal
vec3 oe_UpVectorView;
#pragma vp_varying_in vec3 oe_UpVectorView
vec2 oe_normal_uv;
#pragma vp_varying_in vec2 oe_normal_uv
vec3 oe_normal_binormal;
#pragma vp_varying_in vec3 oe_normal_binormal
// global
mat3 oe_normalMapTBN;
void oe_rex_normalMapFS(inout vec4 color)
{
#ifndef OE_TERRAIN_RENDER_NORMAL_MAP
    return;
#endif
    vec4 N = oe_terrain_getNormalAndCurvature(oe_normal_uv);
    vec3 tangent = normalize(cross(oe_normal_binormal, oe_UpVectorView));
    oe_normalMapTBN = mat3(tangent, oe_normal_binormal, oe_UpVectorView);
    vp_Normal = normalize(oe_normalMapTBN*N.xyz);
#ifdef OE_DEBUG_CURVATURE
    // visualize curvature quantized:
    color.rgba = vec4(0, 0, 0, 1);
    float curvature = N.w;
    if (curvature > 0.0) color.r = curvature;
    if (curvature < 0.0) color.g = -curvature;
#endif
#ifdef OE_DEBUG_NORMALS
    // visualize normals:
    color.rgb = (N.xyz + 1.0)*0.5;
#endif
}

////////////////////////////////////////shaderlist[9]
#version 460
#pragma vp_name       REX Engine - Morphing
#pragma vp_entryPoint oe_rex_morph
#pragma vp_location   vertex_model
#pragma vp_order      0.5
#pragma import_defines(OE_TERRAIN_MORPH_GEOMETRY)
#pragma import_defines(OE_TERRAIN_RENDER_ELEVATION)
#pragma import_defines(OE_IS_DEPTH_CAMERA)
#pragma import_defines(OE_TILE_SIZE)
#define VP_STAGE_VERTEX
vec3 vp_Normal;
#pragma vp_varying_out vec3 vp_Normal
vec4 oe_layer_tilec;
#pragma vp_varying_out vec4 oe_layer_tilec
float oe_rex_morphFactor;
#pragma vp_varying_out float oe_rex_morphFactor
int oe_terrain_vertexMarker;
#pragma vp_varying_out flat int oe_terrain_vertexMarker
uniform vec2 oe_tile_morph;
uniform vec2 oe_tile_elevTexelCoeff;
#ifdef OE_IS_DEPTH_CAMERA
uniform mat4 oe_shadowToPrimaryMatrix;
#endif
// SDK functions:
float oe_terrain_getElevation(in vec2 uv);
// Vertex Markers:
#define VERTEX_VISIBLE  1
#define VERTEX_BOUNDARY 2
#define VERTEX_HAS_ELEVATION 4
#define VERTEX_SKIRT 8
#define VERTEX_CONSTRAINT 16
void moveToConstraint(in vec4 vertex, in vec4 layer_tilec, out vec4 newVertex, out vec4 new_layer_tilec)
{
    newVertex = vertex;
    new_layer_tilec = layer_tilec;
}
// Compute a morphing factor based on model-space inputs:
float oe_rex_ComputeMorphFactor(in vec4 position, in vec3 up)
{
    // Find the  would be  position of the vertex (the position the vertex would
    // assume with no morphing)
	vec4 wouldBePosition = position;
#ifdef OE_TERRAIN_RENDER_ELEVATION
        float elev = oe_terrain_getElevation( oe_layer_tilec.st );
		wouldBePosition.xyz += up*elev;
#endif
    vec4 wouldBePositionView = gl_ModelViewMatrix * wouldBePosition;
#ifdef OE_IS_DEPTH_CAMERA
    // For a depth camera, we have to compute the morphed position
    // from the perspective of the primary camera so they match up:
    wouldBePositionView = oe_shadowToPrimaryMatrix * wouldBePositionView;
#endif
    float fDistanceToEye = length(wouldBePositionView.xyz); // or just -z.
    float fMorphLerpK  = 1.0 - clamp( oe_tile_morph[0] - fDistanceToEye * oe_tile_morph[1], 0.0, 1.0 );
    return fMorphLerpK;
}
void oe_rex_morph(inout vec4 vertexModel)
{
    // compute the morphing factor to send down the pipe.
    // we need this even if vertex-morphing is off since we use it for
    // other things (like image blending)
    if ((oe_terrain_vertexMarker & VERTEX_CONSTRAINT) == 0)
    {
        oe_rex_morphFactor = oe_rex_ComputeMorphFactor(vertexModel, vp_Normal);
#ifdef OE_TERRAIN_MORPH_GEOMETRY
        vec4 neighborVertexModel = vec4(gl_MultiTexCoord1.xyz, 1.0);
        vec3 neighborNormal = gl_MultiTexCoord2.xyz;
        const float halfSize = (0.5*OE_TILE_SIZE)-0.5;
        const float twoOverHalfSize = 2.0/(OE_TILE_SIZE-1.0);
        // Either 0 if point should not be morphed (in (x, y)), or the
        // delta to the neighbor point.
        vec2 fractionalPart = fract(oe_layer_tilec.st * halfSize) * twoOverHalfSize;
        vec4 neighbor_tilec = oe_layer_tilec;
        neighbor_tilec.st = clamp(oe_layer_tilec.st - fractionalPart, 0.0, 1.0);
        // morph the vertex:
        vertexModel.xyz = mix(vertexModel.xyz, neighborVertexModel.xyz, oe_rex_morphFactor);
        // morph the normal:
        vp_Normal = normalize(mix(vp_Normal, neighborNormal, oe_rex_morphFactor));
        oe_layer_tilec.st = mix(oe_layer_tilec.st, neighbor_tilec.st, oe_rex_morphFactor);
#endif
    }
    else
    {
        oe_rex_morphFactor = 0.0;
    }
}

////////////////////////////////////////shaderlist[10]
#version 460
#pragma vp_name       REX Engine - ImageLayer/VS
#pragma vp_entryPoint oe_rex_imageLayer_VS
#pragma vp_location   vertex_view
#pragma vp_order      0.4
#define VP_STAGE_VERTEX
// Stage globals
vec4 oe_layer_tilec;
vec2 oe_layer_texc;
vec2 oe_layer_texcParent;
uniform mat4 oe_layer_texMatrix;
uniform mat4 oe_layer_texParentMatrix;
void oe_rex_imageLayer_VS(inout vec4 vertexView)
{
    // calculate the texture coordinates:
    oe_layer_texc = (oe_layer_texMatrix * oe_layer_tilec).st;
    oe_layer_texcParent = (oe_layer_texParentMatrix * oe_layer_tilec).st;
}

////////////////////////////////////////shaderlist[11]
#version 460
#pragma vp_name       REX Engine - Fragment
#pragma vp_entryPoint oe_rex_imageLayer_FS
#pragma vp_location   fragment_coloring
#pragma vp_order      0.5
#pragma import_defines(OE_TERRAIN_RENDER_IMAGERY)
#pragma import_defines(OE_TERRAIN_MORPH_IMAGERY)
#pragma import_defines(OE_TERRAIN_BLEND_IMAGERY)
#pragma import_defines(OE_TERRAIN_CAST_SHADOWS)
#pragma import_defines(OE_IS_PICK_CAMERA)
#pragma import_defines(OE_IS_SHADOW_CAMERA)
#pragma import_defines(OE_IS_DEPTH_CAMERA)
#define VP_STAGE_FRAGMENT
uniform sampler2D oe_layer_tex;
uniform int       oe_layer_uid;
uniform int       oe_layer_order;
#ifdef OE_TERRAIN_MORPH_IMAGERY
uniform sampler2D oe_layer_texParent;
uniform float oe_layer_texParentExists;
vec2 oe_layer_texcParent;
#pragma vp_varying_in vec2 oe_layer_texcParent
float oe_rex_morphFactor;
#pragma vp_varying_in float oe_rex_morphFactor
#endif
vec2 oe_layer_texc;
#pragma vp_varying_in vec2 oe_layer_texc
vec4 oe_layer_tilec;
#pragma vp_varying_in vec4 oe_layer_tilec
float oe_layer_opacity;
#pragma vp_varying_in float oe_layer_opacity
// Vertex Markers:
#define VERTEX_VISIBLE  1
#define VERTEX_BOUNDARY 2
#define VERTEX_HAS_ELEVATION 4
#define VERTEX_SKIRT 8
int oe_terrain_vertexMarker;
#pragma vp_varying_in flat int oe_terrain_vertexMarker
void oe_rex_imageLayer_FS(inout vec4 color)
{
    // if the provoking vertex is marked for discard, skip it:
    if ((oe_terrain_vertexMarker & VERTEX_VISIBLE) == 0)
    {
        discard;
        return;
    }
    // If this is a shadow camera and the terrain doesn't cast shadows, no render:
#if defined(OE_IS_SHADOW_CAMERA) && !defined(OE_TERRAIN_CAST_SHADOWS)
    discard;
    return;
#endif
    // If this is a depth-only camera, skip terrain skirt geometry:
#if defined(OE_IS_DEPTH_CAMERA)
    if ((oe_terrain_vertexMarker & VERTEX_SKIRT) != 0)
    {
        discard;
        return;
    }
#endif // OE_IS_DEPTH_CAMERA
    // if this is a picking camera, reset the color to all zeros:
#ifdef OE_IS_PICK_CAMERA
    color = vec4(0);
#else
    // If imagery rendering is disabled, we're done:
#ifndef OE_TERRAIN_RENDER_IMAGERY
    return;
#endif
    // whether this layer contains texel color (UID<0 means no texture)
    bool isTexelLayer = oe_layer_uid >= 0;
    // whether this is the first layer to render:
    bool isFirstLayer = oe_layer_order == 0;
    vec4 texel = color;
    if (isTexelLayer)
    {
        texel = texture(oe_layer_tex, oe_layer_texc);
#ifdef OE_TERRAIN_MORPH_IMAGERY
        // sample the main texture:
        // sample the parent texture:
        vec4 texelParent = texture(oe_layer_texParent, oe_layer_texcParent);
        // if the parent texture does not exist, use the current texture with alpha=0 as the parent
        // so we can  fade in  an image layer that starts at LOD > 0:
        texelParent = mix(vec4(texel.rgb, 0.0), texelParent, oe_layer_texParentExists);
        // Resolve the final texel color.
        // We have to clamp oe_rex_morphFactor here even though it's clamped in the 
        // vertex shader. Reason unknown.
        texel = mix(texel, texelParent, clamp(oe_rex_morphFactor, 0.0, 1.0));
#endif
        // intergrate thelayer opacity:
        texel.a = texel.a * oe_layer_opacity;
        color.a = 1.0;
    }
#ifdef OE_TERRAIN_BLEND_IMAGERY
    // If this is a first image layer, blend with the incoming terrain color.
    // Otherwise, apply directly and let GL blending do the rest.
    if (isTexelLayer && isFirstLayer)
    {
        color.rgb = texel.rgb*texel.a + color.rgb*(1.0 - texel.a);
    }
    else
    {
        color = texel;
    }
#else
    // No blending? The output is just the texel value.
    color = texel;
#endif // OE_TERRAIN_BLEND_IMAGERY
#endif // OE_IS_PICK_CAMERA
}

////////////////////////////////////////shaderlist[12]
#version 460
void myfunc_vertexmodel(inout vec4 vertex){
			}

////////////////////////////////////////shaderlist[13]
#version 460
void myfunc_vertexclip(inout vec4 vertex){
			}

////////////////////////////////////////shaderlist[14]
#version 460
void myfunc_vertexview(inout vec4 vertex){
			}

////////////////////////////////////////shaderlist[15]
#version 460
void myfunc_fragmentcoloring(inout vec4 color){
			}

////////////////////////////////////////shaderlist[16]
#version 460
void myfunc_fragmentlighting(inout vec4 color){
			}

////////////////////////////////////////shaderlist[17]
#version 460
void myfunc_fragmentoutput(inout vec4 color){
			}

////////////////////////////////////////shaderlist[18]
#version 460
uniform float oe_VisibleLayer_opacityUniform;
float oe_layer_opacity;
#pragma vp_varying_out float oe_layer_opacity
void oe_VisibleLayer_initOpacity(inout vec4 vertex)
        {
            oe_layer_opacity = clamp(oe_VisibleLayer_opacityUniform, 0.0, 1.0);
        }

////////////////////////////////////////shaderlist[19]
#version 460
#pragma import_defines(OE_USE_ALPHA_TO_COVERAGE)
#pragma import_defines(OE_SELF_MANAGE_LAYER_OPACITY)
float oe_layer_opacity;
#pragma vp_varying_in float oe_layer_opacity
void oe_VisibleLayer_setOpacity(inout vec4 color)
        {
          #if defined(OE_SELF_MANAGE_LAYER_OPACITY) || defined(OE_USE_ALPHA_TO_COVERAGE)
            return;
          #endif

          color.a *= oe_layer_opacity;
        }

////////////////////////////////////////shaderlist[20]
#version 460
#pragma vp_name VP Vertex Shader Main 

// Vertex stage globals:
int oe_terrain_vertexMarker; 
float oe_layer_opacity; 
float oe_rex_morphFactor; 
vec2 oe_layer_texc; 
vec2 oe_layer_texcParent; 
vec2 oe_normal_uv; 
vec3 oe_UpVectorView; 
vec3 oe_normal_binormal; 
vec3 vp_Normal; 
vec3 vp_VertexView; 
vec4 oe_layer_tilec; 
vec4 vp_Color; 
vec4 vp_Vertex; 

// Vertex stage outputs:
out VP_PerVertex { 
    flat int oe_terrain_vertexMarker; 
    float oe_layer_opacity; 
    float oe_rex_morphFactor; 
    vec2 oe_layer_texc; 
    vec2 oe_layer_texcParent; 
    vec2 oe_normal_uv; 
    vec3 oe_UpVectorView; 
    vec3 oe_normal_binormal; 
    vec3 vp_Normal; 
    vec3 vp_VertexView; 
    vec4 oe_layer_tilec; 
    vec4 vp_Color; 
    vec4 vp_Vertex; 
} vp_out; 

// Function declarations:
void oe_rex_init_model(inout vec4); 
void oe_rex_morph(inout vec4); 
void myfunc_vertexmodel(inout vec4); 
void oe_VisibleLayer_initOpacity(inout vec4); 
void oe_rex_init_view(inout vec4); 
void oe_rex_applyElevation(inout vec4); 
void oe_rex_imageLayer_VS(inout vec4); 
void oe_rex_normalMapVS(inout vec4); 
void myfunc_vertexview(inout vec4); 
void oe_ClipPlane_vs(inout vec4); 
void myfunc_vertexclip(inout vec4); 

void main(void) 
{ 
    vp_Vertex = gl_Vertex; 
    vp_Normal = gl_Normal; 
    vp_Color  = gl_Color; 
    oe_rex_init_model(vp_Vertex); 
    oe_rex_morph(vp_Vertex); 
    myfunc_vertexmodel(vp_Vertex); 
    oe_VisibleLayer_initOpacity(vp_Vertex); 
    vp_Vertex = gl_ModelViewMatrix * vp_Vertex; 
    vp_Normal = normalize(gl_NormalMatrix * vp_Normal); 
    vp_VertexView = vp_Vertex.xyz;
    oe_rex_init_view(vp_Vertex); 
    oe_rex_applyElevation(vp_Vertex); 
    oe_rex_imageLayer_VS(vp_Vertex); 
    oe_rex_normalMapVS(vp_Vertex); 
    myfunc_vertexview(vp_Vertex); 
    oe_ClipPlane_vs(vp_Vertex); 
    vp_Vertex = gl_ProjectionMatrix * vp_Vertex; 
    myfunc_vertexclip(vp_Vertex); 
    gl_Position = vp_Vertex; 
    vp_out.oe_terrain_vertexMarker = oe_terrain_vertexMarker; 
    vp_out.oe_layer_opacity = oe_layer_opacity; 
    vp_out.oe_rex_morphFactor = oe_rex_morphFactor; 
    vp_out.oe_layer_texc = oe_layer_texc; 
    vp_out.oe_layer_texcParent = oe_layer_texcParent; 
    vp_out.oe_normal_uv = oe_normal_uv; 
    vp_out.oe_UpVectorView = oe_UpVectorView; 
    vp_out.oe_normal_binormal = oe_normal_binormal; 
    vp_out.vp_Normal = vp_Normal; 
    vp_out.vp_VertexView = vp_VertexView; 
    vp_out.oe_layer_tilec = oe_layer_tilec; 
    vp_out.vp_Color = vp_Color; 
    vp_out.vp_Vertex = vp_Vertex; 
} 

////////////////////////////////////////shaderlist[21]
#version 460
#pragma vp_name VP Fragment Shader Main

// Fragment stage inputs:
in VP_PerVertex { 
    flat int oe_terrain_vertexMarker; 
    float oe_layer_opacity; 
    float oe_rex_morphFactor; 
    vec2 oe_layer_texc; 
    vec2 oe_layer_texcParent; 
    vec2 oe_normal_uv; 
    vec3 oe_UpVectorView; 
    vec3 oe_normal_binormal; 
    vec3 vp_Normal; 
    vec3 vp_VertexView; 
    vec4 oe_layer_tilec; 
    vec4 vp_Color; 
    vec4 vp_Vertex; 
} vp_in; 

// Fragment stage globals:
int oe_terrain_vertexMarker;
float oe_layer_opacity;
float oe_rex_morphFactor;
vec2 oe_layer_texc;
vec2 oe_layer_texcParent;
vec2 oe_normal_uv;
vec3 oe_UpVectorView;
vec3 oe_normal_binormal;
vec3 vp_Normal;
vec3 vp_VertexView;
vec4 oe_layer_tilec;
vec4 vp_Color;
vec4 vp_Vertex;

// Function declarations:
void oe_pbr_init(inout vec4 color); 
void oe_rex_normalMapFS(inout vec4 color); 
void oe_rex_imageLayer_FS(inout vec4 color); 
void myfunc_fragmentcoloring(inout vec4 color); 
void oe_VisibleLayer_setOpacity(inout vec4 color); 
void myfunc_fragmentlighting(inout vec4 color); 
void myfunc_fragmentoutput(inout vec4 color); 

void main(void) 
{ 
    oe_terrain_vertexMarker = vp_in.oe_terrain_vertexMarker; 
    oe_layer_opacity = vp_in.oe_layer_opacity; 
    oe_rex_morphFactor = vp_in.oe_rex_morphFactor; 
    oe_layer_texc = vp_in.oe_layer_texc; 
    oe_layer_texcParent = vp_in.oe_layer_texcParent; 
    oe_normal_uv = vp_in.oe_normal_uv; 
    oe_UpVectorView = vp_in.oe_UpVectorView; 
    oe_normal_binormal = vp_in.oe_normal_binormal; 
    vp_Normal = vp_in.vp_Normal; 
    vp_VertexView = vp_in.vp_VertexView; 
    oe_layer_tilec = vp_in.oe_layer_tilec; 
    vp_Color = vp_in.vp_Color; 
    vp_Vertex = vp_in.vp_Vertex; 
    vp_Normal = normalize(vp_Normal); 
    oe_pbr_init( vp_Color ); 
    oe_rex_normalMapFS( vp_Color ); 
    oe_rex_imageLayer_FS( vp_Color ); 
    myfunc_fragmentcoloring( vp_Color ); 
    oe_VisibleLayer_setOpacity( vp_Color ); 
    myfunc_fragmentlighting( vp_Color ); 
    myfunc_fragmentoutput( vp_Color ); 
}

